/**************************************************
|	File:		Player.h
|	Author:		Benjamin Budian
|	Course:		SGD
|	Purpose:	Player class handles all things player related
**************************************************/

#pragma once
#include "entity.h"
#include "../SGD Wrappers/IListener.h"
#include "CreateProjectileMessage.h"

class CCellAnimation;
class CPlayer :
	public CEntity, public IListener
{
public:
	CPlayer			(void);
	virtual ~CPlayer(void);

	void Initialize	( int nPlayerType );
	void Input		();
	
	virtual void Update			( float fElapsedTime	)	override;
	virtual void Render			( )							override;
	virtual void HandleCollision( const IEntity* pOther )	override;

	virtual void HandleEvent( CEvent* pEvent )	override;
	 
	//Accessors
	float	GetDamage	( void ) const	{	return	m_fDamageMultiplier;	}
	short	GetHealth	( void ) const  {	return	m_sHealth;	}
	short	GetMana		( void ) const	{	return	m_sMana;	}
	short	GetKills	( void ) const	{	return m_sKills;	}

	//Mutators
	void	SetDamage	( float fDamage )	{	m_fDamageMultiplier	= fDamage;	}
	void	SetHealth	( short sHealth	)	{	m_sHealth	= sHealth;	}
	void	SetMana		( short sMana	)	{	m_sMana		= sMana;	}
	void	SetFireTimer( float fFireTimer);
	void	SetArmor	( unsigned char cArmor) { m_cArmor = cArmor;				}
	void	SetArmor	( int nArmorPiece );

	//Other Methods
	void	TakeDamage	( short sDamage )	{	m_sHealth -= (sDamage-m_sArmor);	}
	void	UpdateKills ( short sKill = 1 )	{	m_sKills += sKill;		}
	void	GameOver	( bool bGameOver = false ) { m_bGameOver = bGameOver; }
	void	SetDebugMode( bool bDebug )		{ m_bDebug = bDebug; }


private:

	//Movement Direction Starting Animation Row
	enum PlayerMovementDirection	{ PLAYER_MOVE_UP = 104, PLAYER_MOVE_DOWN = 130, PLAYER_MOVE_LEFT = 117, PLAYER_MOVE_RIGHT = 143 };
	//Attack Direction Starting Animation Row
	enum PlayerAttackDirection		{ PLAYER_ATTACK_UP, PLAYER_ATTACK_LEFT, PLAYER_ATTACK_DOWN, PLAYER_ATTACK_RIGHT };
	enum PlayerWeapon				{ SWORD = 12, BOW = 16 };
	enum ArmorValues				{ HEAD_VALUE = 2, SHOULDER_VALUE = 1, LEGS_VALUE = 4, HANDS_VALUE = 1, FEET_VALUE = 2, CHEST_VALUE = 8 };
	enum NumberWeaponCells			{ SPEAR_CELLS = 8, SWORD_CELLS = 6, BOW_CELLS = 13 };

	CCellAnimation* PlayerAnimation;
	CCellAnimation* PlayerWeaponAnimation;
	CCellAnimation* ArmorAnimations[6];

	int m_nHealthBarImgID;

	///////////////////
	//	Player attributes
	short m_sHealth;
	short m_sMana;
	short m_sKills;
	short m_sArmor;
	///////////////////
	
	///////////////////
	//	Timers
	float m_fDamageMultiplier;
	float m_fFireTimer;
	float m_fMaxFireTimer;
	float m_fPlaySpeed;
	///////////////////

	///////////////////
	//	Booleans
	bool m_bGameOver;
	bool m_bInvincible;
	bool m_bDebug;
	///////////////////

	///////////////////
	//	Bytes
	unsigned char m_cArmor;
	unsigned char weapons;
	///////////////////
	
	//Weapon animation row
	PlayerWeapon			m_eWeapon;
	//Weapon Animation End Cell
	NumberWeaponCells		m_eCurrentWeaponEndCell;
	//Movement Animation Row
	PlayerMovementDirection m_eMovementDirection;
	//Projectile image tile
	Projectile_Directions	m_eProjectileDirection;

	//Private Helper Functions

	///////////////////
	// StayInWorld() - Checks to see if the player has left the bounds of the world.
	//					if so keeps player within appropriate bounds.
	void StayInWorld();

	void SwitchWeapons(PlayerWeapon eWeapon);
	void ChangeDirection(PlayerMovementDirection eDirection, PlayerAttackDirection eAttackDirection, float fVelX, float fVelY);
	void ChangeAttackDirection(PlayerAttackDirection eAttackDirection);
	void Attack(PlayerAttackDirection eAttackDirection, Projectile_Directions eProjectileDirection);
	void SetupArmor();
};

